import CompoundPath = require('./../../common/graph/CompoundPath');
import CommonModel = require('./../../common/model/CommonModel');
import ObjPosition = require('./../base/ObjPosition');
import ObjPositionAlign = require('./../base/ObjPositionAlign');
import ObjConstrain = require('./../base/ObjConstrain');
import FColorBase = require('./../color/FColorBase');
import SJGReplaceGroup = require('./../replace/SJGReplaceGroup');
import GCJ_CLASS_TYPE = require('./../../common/GCJ_CLASS_TYPE');
import DEFINE = require('./../../common/DEFINE');
import Serializer = require('./../base/Serializer');
import Parser = require('./../base/Parser');
import PageInfo=require('./../../common/PageInfo');
var async  = require( 'async'); // 同步控制
var fs = require('fs')
var SJGSelectRect;
var path=require('path');
var CONFIG=require('../../../../common/config');
var CommonUtil=require('../../../../common/util/CommonUtil');

export  = ObjBase;

/**
 *
 * @author 
 *
 */
class ObjBase extends Serializer{
    public static OBJ_UNLOCK: number=0;
    public static OBJ_LOCK: number=1;
    
    public static PAGE_BACKGROUND_NO: number=0;// 页背景－不是
    public static PAGE_BACKGROUND_YES: number=1;// 页背景－是
    
    public static REPLACE_OBJ_NO: number=0;// 普通对象
    public static REPLACE_OBJ_YES: number=1;// 可替换对象
    
    public id:number = DEFINE.ID_NONE; // 自己的id
    
    public pos:ObjPosition = new ObjPosition(); // 自己的位置尺寸
    
    public al:number = 1;// alpha 透明度
    public color:FColorBase = null;// 填充颜色
    public strokecolor: FColorBase = null;// 描边颜色
    public strokewidth: number=0;// 描边线宽
    
    public bgal: number=1; // 背景 alpha 透明度
    public bgcolor:FColorBase = null; // 背景颜色
    
    public mask:CompoundPath = null; // 蒙板对象
    public name:string = null; // 名称 
    public constrain:ObjConstrain = new ObjConstrain(); // 约束，ObjConstrain类型
    public lock: number=ObjBase.OBJ_UNLOCK; // 0:lock/1:unlock
    
    public background: ObjBase=null; // 背景对象,每个对象都可以单独添加背景
    public align: ObjPositionAlign=null; // 各种ReplaceGroupObj的内部编组使用，用来控制对齐 [废弃?]
    
    public pagebk: number=ObjBase.PAGE_BACKGROUND_NO;// 是否为页的背景
    public replaceFlg: number=ObjBase.REPLACE_OBJ_NO;// 是否为可替换对象

    // 20161118 新增 start-----------------------
    public h: number=0; // 1表示隐藏／0表示显示
    // ---------------------------------------end
    
    // 以下变量编辑器使用，不需要序列化
    public parent: ObjBase=null;// 建立子对父的引用，临时用
    public copyFromId: number=null;// 复制对象时，临时用
    
    
	public constructor(g?) {
        super(g);
	}
  
    // 从json对象(注意不是json字符串)中解析
	// 参数：self,true表示只拷贝自身数据，而不拷贝子的数据
    public fromJson(jsonObj,versionId,self?) { 
        super.fromJson(jsonObj,versionId,self);

        this.id=jsonObj.id;
        if(jsonObj.pos!=null) {
            this.pos.fromJson(jsonObj.pos,versionId);
        }

        this.al=jsonObj.al;
        if(jsonObj.color!=null) {
            this.color=Parser.fromUnknownJson(jsonObj.color,versionId);
        }
        if(jsonObj.strokecolor!=null) {
            this.strokecolor=Parser.fromUnknownJson(jsonObj.strokecolor,versionId);
        }
        if(jsonObj.bgcolor!=null) {
            this.bgcolor=Parser.fromUnknownJson(jsonObj.bgcolor,versionId);
        }
        if(jsonObj.hasOwnProperty("bgal")) {
            this.bgal=jsonObj.bgal;
        }
        this.strokewidth=jsonObj.strokewidth;
        if(jsonObj.mask!=null) {
            this.mask=new CompoundPath();
            this.mask.fromJson(jsonObj.mask,versionId);
        }
        if(jsonObj.name!=null) {
            this.name=jsonObj.name;
        }
        if(jsonObj.constrain!=null) {
            this.constrain.fromJson(jsonObj.constrain,versionId);
        }
        if(jsonObj.hasOwnProperty("lock")) {
            this.lock=jsonObj.lock;
        }
        if(jsonObj.hasOwnProperty("background")) {
            this.background=Parser.fromUnknownJson(jsonObj.background,versionId,this.getGlobalData());
        }
        
        if(jsonObj.hasOwnProperty("align")&&jsonObj.align) {
            this.align=new ObjPositionAlign(this.getGlobalData());
            this.align.fromJson(jsonObj.align,versionId);
        }
        if(jsonObj.hasOwnProperty("pagebk")) {
            this.pagebk=jsonObj.pagebk;
        }
        
        if(jsonObj.hasOwnProperty("replaceFlg")) {
            this.replaceFlg=jsonObj.replaceFlg;
        }

        if(jsonObj.hasOwnProperty("h")) {
            this.h=jsonObj.h;
        }
    }
    // 最小化TextExt转换成Json:所有页root对象只保留TextExtObj(且只保留fz\te\style\color\id\pos几个属性)
    public toJsonOfMinTextExt():string{
        var superJson =super.toJson();
        superJson=superJson.substr(1,superJson.length-2);

        var ret ="{";
        ret+=superJson;

        // id
        ret+=",";
        ret+="\"id\":";
        ret+=this.id;

        // pos
        ret+=",";
        ret+="\"pos\":";
        ret+=this.pos.toJson();


        // color
        if(this.color) {
            ret+=",";
            ret+="\"color\":";
            ret+=this.color.toJson();
        }

        // h
        ret+=',';
        ret+='"h":';
        ret+=this.h;

        ret+="}";
        return ret;
    }
    // 转成json字符串
    public toJson():string {
        // 去掉父json字符串的头尾
        var superJson = super.toJson();
        superJson = superJson.substr(1,superJson.length-2);
                
        var ret = '{';
        ret +=superJson;
                    
        // id
        ret +=',';
        ret += '"id":';
        ret += this.id;
        
        // pos
        if(this.pos!=null){ 
            ret +=',';
            ret += '"pos":';
            ret += this.pos.toJson();              
        }
        
        // al
        ret +=',';
        ret += '"al":';
        ret += this.al;
        
        // color
        if(this.color!=null){
            ret +=',';
            ret += '"color":';
            ret += this.color.toJson();
        }
        // strokecolor
        if(this.strokecolor!=null){
            ret += ',';
            ret += '"strokecolor":';
            ret += this.strokecolor.toJson();
        }
        // bgcolor
        if(this.bgcolor!=null){
            ret +=',';
            ret += '"bgcolor":';
            ret += this.bgcolor.toJson();
        }
        // bgal
        if(this.bgal!=null) {
            ret+=',';
            ret+='"bgal":';
            ret+=this.bgal;
        }
        
        // strokewidth
        if (this.strokewidth!= null){
            ret += ',';
            ret += '"strokewidth":';
            ret += this.strokewidth;
        }
        // mask
        if(this.mask!=null){ 
            ret +=',';
            ret += '"mask":';
            ret += this.mask.toJson();    
        }
        // name
        if(this.name!=null){ 
            ret +=',';
            ret += '"name":'+'"';
            ret += this.name+'"';
        }
        // constrain
        if(this.constrain!=null){
            ret +=',';
            ret += '"constrain":';
            ret += this.constrain.toJson();
        }       
        
        // lock
        ret+=',';
        ret+='"lock":';
        ret+=this.lock;
        
        // background
        if(this.background!=null) {
            ret+=',';
            ret+='"background":';
            ret+=this.background.toJson();
        }  
        
        // align
        if(this.align!=null) {
            ret+=',';
            ret+='"align":';
            ret+=this.align.toJson();
        } 
        
        // pagebk
        ret+=',';
        ret+='"pagebk":';
        ret+=this.pagebk;
        
        // replaceFlg
        ret+=',';
        ret+='"replaceFlg":';
        ret+=this.replaceFlg;

        // h
        ret+=',';
        ret+='"h":';
        ret+=this.h;
        
        
        ret+='}';
        return ret;
    }
    
    // 添加子对象，能够添加子对象的对象重载
    // 参数：child 待添加的字对象
    // 参数：insertIndex 待添加的位置
    // 参数：flag 操作flag，ObjBase的不同子对象有不同含义
    public addChild(child:ObjBase,insertIndex:number, flag:number=0):boolean{
        return false;
    }
    //  获得子对象的id，能够添加子对象的对象重载
    public getChildIds():Array<number>{
        return [];
    }
    // 获得某种类型的子对象，能够添加子对象的对象重载
    public getChildOfType(ct: number,reverse: Boolean=false, recursive:Boolean=false):Array<number>{
        return [];
    }
    public getChildObjOfType(ct: number,reverse: Boolean=false,recursive: Boolean=false): Array<ObjBase> {
        return [];
    }
    // 获得某种类型的子对象，能够添加子对象的对象重载
    public getChildOfTypes(cts: Array<number>,reverse: Boolean=false,recursive: Boolean=false): Array<number> {
        return [];
    }
    // 获得某种类型的兄弟对象，能够添加子对象的对象重载
    public getSiblingOfType(ct: number,reverse: Boolean=false): Array<number> {
        var ret: Array<number>=new Array<number>();
        if(this.parent) { 
            var sibs = this.parent.getChildOfType(ct,reverse,false);
            for(var i=0;i<sibs.length;i++){
                if(sibs[i]==this.id) { 
                    sibs.splice(i,1);
                    break;
                }
            }
            ret=ret.concat(sibs);
        }
        
        
        
        return ret;
    }

    // 删除子对象，能够添加子对象的对象重载
    public removeChild(id:number){
        
    }
    
    // 删除子对象，能够添加子对象的对象重载
    public removeChilds(ids: Array<number>) {

    }
    // 删除所有子对象，能够添加子对象的对象重载
    public removeAllChild(){
                
    }
    // 是否简单对象[非Group对象，非以及Group对象的派生]
    public isSimple():boolean{
        return true;
    }
    
    // 扩展大小
    // 参数：controlType 控制点类型，值为：0 上/1 右/2 下/3 左/4 中间，见SJGSelectRect.CONTROL_*
    // 参数：ratioX x缩放比例
    // 参数：ratioY y缩放比例
    // 参数：outside true表示操作所在的最外层对象，false表示内部对象
    public expand(controlType:number,ratioX: number,ratioY: number,outside:boolean){
        // 如果不能缩放对象，则按照中心点进行偏移；否则按左上角进行偏移和缩放
        if(this.constrain.scale==0){
            
            if(0==controlType) {
                
            } else if(1==controlType) {
                //this.pos.x=this.pos.x*ratioX+(ratioX-1)*this.pos.w/2;
                var oldW=this.parent.pos.w/ratioX;
                this.pos.x=(ratioX-1)/2*oldW+this.pos.x;

            } else if(2==controlType) {
                //this.pos.y=this.pos.y*ratioY+(ratioY-1)*this.pos.h/2;
                var oldH=this.parent.pos.h/ratioY;
                this.pos.y=(ratioY-1)/2*oldH+this.pos.y;
            } else if(3==controlType) {
                
            }
            
            
        }else{
            if(0==controlType) {
                if(outside) {
                    this.pos.y+=this.pos.h*(1-ratioY);
                    this.pos.h*=ratioY;
                } else {
                    this.pos.y*=ratioY;
                    this.pos.h*=ratioY;
                }
            } else if(1==controlType) {
                if(outside) {
                    this.pos.w*=ratioX;
                } else {
                    this.pos.x*=ratioX;
                    this.pos.w*=ratioX;
                }

            } else if(2==controlType) {
                if(outside) {
                    this.pos.h*=ratioY;
                } else {
                    this.pos.y*=ratioY;
                    this.pos.h*=ratioY;
                }

            } else if(3==controlType) {
                if(outside) {
                    this.pos.x+=this.pos.w*(1-ratioX);
                    this.pos.w*=ratioX;
                } else {
                    this.pos.x*=ratioX;
                    this.pos.w*=ratioX;
                }

            }else if(4==controlType) {// 中间
                if(outside) {
                    this.pos.x+=this.pos.w*(1-ratioX)/2;
                    this.pos.y+=this.pos.h*(1-ratioY)/2;
                    this.pos.w*=ratioX;
                    this.pos.h*=ratioY;
                } else {
                    // TODO
                }
            } else if(12==controlType) {// 右下
                if(outside) {
                    this.pos.w*=ratioX;
                    this.pos.h*=ratioY;
                } else {
                    this.pos.x*=ratioX;
                    this.pos.w*=ratioX;
                    this.pos.y*=ratioY;
                    this.pos.h*=ratioY;
                }
            }
            // 如果有mask，则调整mask
            if(this.mask!=null) {
                if(0==controlType||2==controlType) {
                    this.mask.adjustPosition(1,ratioY,2);
                } else if(1==controlType||3==controlType) {
                    this.mask.adjustPosition(ratioX,1,2);
                }

            }
        }
    }
    
    // 上移／下移一层
    // 参数：obj 从父对象中删除obj
    // 参数：up true向上移动
    public MSG_UI_MOVE_UP_DOWN(obj:ObjBase, up: Boolean) {
        
    }
    
    // 获取对象名称
    public getObjetName():string{
        return "基类";
    }
    
    // 设置lock为非锁定状态
    public clearLock(){
        this.lock=ObjBase.OBJ_UNLOCK;
    }
    
    // 缩放对象
    public scale(s:number) { 
        this.pos.multiply(s);
        
        if(this.mask){
            this.mask.adjustPosition(s,s,2);
        }
    }
    
    // 转换成CommonModel树
    public toCommonModel(level:number): CommonModel{
        var spread=this.isSimple()? CommonModel.SPREAD_NONE:CommonModel.SPREAD_COLLAPSE;
        
        var value=this.getObjetName()+"@"+this.id+"("+Math.round(this.pos.x)+","+Math.round(this.pos.y)+")";
        if(this.replaceFlg==ObjBase.REPLACE_OBJ_YES) {
            // 可替换对象标红
            value='<span style="color:red">'+value+'</span>';
        }
        
        return CommonModel.from(this.id,value,spread,level);
    }
    
    // 深度更新id［处理自身和子对象，递归］
    // 参数：idMaps，新旧id的对应关系, 例如：[{oldId:1,newId:2}]
    public deepResetId(idMaps: Array<any>){
        var oldId=this.id;
        this.id=this.getGlobalData().idGenerator().newId(); // 分配新id
        this.getGlobalData().objManager().saveObject(this);// 保存到对象管理器
        
        idMaps.push({ oldId:oldId, newId:this.id });

    }
    
    //  根据对齐方式来设置对象位置
    public setObjPostionByAlign(alignPos: ObjPositionAlign) {
        this.align=new ObjPositionAlign();
        this.align.copy(alignPos);
        
        // 根据对齐方式计算本对象的位置
        this.pos=this.align.toPos();
    }
    // 根据参数计算内部数据：例如文字根据字体字号计算轮廓
    public refresh(replace:SJGReplaceGroup=null) {
        
    }

    //  升级数据，需要升级到接口实现
    public upgradeData(){
        
    }

    // 根据id查找对象
    public getChildById(objId) {
        return (this.id==objId)?this:null;
    }
    

    
//SJG_MARK_APPEND--------------------

    /* 检查数据的有效性.
     * 方式:GET
     * 参数:pc:1表示从pc来的请求/为空或者其它值表示从手机来的请求
     * 参数:docId:用户文档id
     * 返回:对象，属性如下：
     *          error:错误内容，null表示没有错误
     *          message:消息
     * */
    public validate() {
        return {error:null,message:''};
    }

}//SJG_MARK_END-------------------------